package com.bc.commoncore.util;

import com.bc.commoncore.security.AES;
import com.bc.commoncore.security.DES;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ParseHelper {
	protected static final Logger logger = LoggerFactory.getLogger(ParseHelper.class);
	
	public static final int DATE_ADD_MINUTE=4;// 增加日期按照分钟增加
	
	public static short ToShort(Object o, short defaultValue) {
		short result = defaultValue;
		try {
			result = Short.parseShort(o.toString());
		} catch (Exception e) {

		}
		return result;
	}

	/**
	 * 
	 * @param o
	 * @return
	 */
	public static short ToShort(Object o) {
		return ToShort(o, (short) 0);
	}

	public static String ToString(Object o, String defaultValue) {
		if (o == null) {
			return defaultValue;
		}
		return o.toString();
	}

	public static int ToInt(Object o, int defaultValue) {
		int result = defaultValue;
		if (o == null) {
			return result;
		}
		try {
			result = Integer.parseInt(o.toString());
		} catch (Exception e) {

		}
		return result;
	}

	/**
	 * 
	 * @param o
	 * @return
	 */
	public static int ToInt(Object o) {
		return ToInt(o, 0);
	}

	/**
	 * 
	 * @param o
	 * @param defaultValue
	 * @return
	 */
	public static long ToLong(Object o, long defaultValue) {
		long result = defaultValue;
		try {
			result = Long.parseLong(o.toString());
		} catch (Exception e) {

		}
		return result;
	}

	/**
	 * 
	 * @param o
	 * @param defaultValue
	 * @return
	 */
	public static double ToDouble(Object o, double defaultValue) {
		double result = defaultValue;
		try {
			result = Double.parseDouble(o.toString());
		} catch (Exception e) {

		}
		return result;
	}

	/**
	 * 
	 * @param o
	 * @param strFormat
	 * @return
	 * @throws ParseException
	 */
	public static Date ToDate(String o) {
		if (StringUtils.isEmpty(o)) {
			return null;
		}
		String time=o.replace("T", " ").replace("/", "-");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if (time.length() == 10) {
			sdf = new SimpleDateFormat("yyyy-MM-dd");
		} else if (time.length() < 10) {
			sdf = new SimpleDateFormat("yyyy-M-d");
		}
		Date defaultDate = null;
		try {
			defaultDate = sdf.parse(time);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return defaultDate;
	}

	/**
	 * 
	 * @param o
	 * @param strFormat
	 * @return
	 * @throws ParseException
	 */
	public static Date ToDate(String o, String strFormat){
		if (strFormat == null || strFormat.isEmpty()) {
			strFormat = "yyyy-MM-dd HH:mm:ss";
		}
		if (StringUtils.isEmpty(o)) {
			return null;
		}
		String time=o.replace("T", " ").replace("/", "-");
		SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
		Date defaultDate = null;
		try {
			defaultDate = sdf.parse(time);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return defaultDate;
	}

	/**
	 * 
	 * @param o
	 * @param strFormat
	 * @return
	 */
	public static String ToDateString(Date o, String strFormat) {
		if (o == null) {
			return "";
		}
		if (strFormat == null || strFormat.isEmpty()) {
			strFormat = "yyyy-MM-dd HH:mm:ss";
		}
		DateFormat sdf = new SimpleDateFormat(strFormat);
		String defaultDate = "";
		defaultDate = sdf.format(o);
		return defaultDate;
	}

	/**
	 * 
	 * @param o
	 * @return
	 */
	public static String ToDateString(Date o) {
		return ToDateString(o, null);
	}

	/**
	 * 
	 * @param o
	 * @return
	 */
	public static String ShowString(Object o) {
		if (o == null) {
			return "";
		} else {
			return o.toString();
		}
	}

	/**
	 * 日期加减帮助方法
	 * 
	 * @author 赵海龙
	 * @Date 20150817
	 * @param dt
	 *            要操作的日期对象
	 * @param type
	 *            0是年，1是月，2是日,3是小时，4是分钟，5是秒
	 * @param dif
	 *            需要加减的值，负数时，表示减
	 * @return
	 */
	public static Date plusDate(Date dt, int type, int dif) {
		Calendar rightNow = Calendar.getInstance();
		return plusDate(rightNow,dt,type,dif);
	}
	/**
	 * 日期加减帮助方法
	 * 
	 * @author 赵海龙
	 * @Date 20150817
	 * @param dt
	 *            要操作的日期对象
	 * @param type
	 *            0是年，1是月，2是日,3是小时，4是分钟，5是秒
	 * @param dif
	 *            需要加减的值，负数时，表示减
	 * @return
	 */
	public static Date plusDate(Calendar rightNow,Date dt, int type, int dif) {
		rightNow.setTime(dt);
		switch (type) {
		case 0:
			rightNow.add(Calendar.YEAR, dif);// 日期加n年
			break;
		case 1:
			rightNow.add(Calendar.MONTH, dif);// 日期加n月
			break;
		case 2:
			rightNow.add(Calendar.DAY_OF_YEAR, dif);// 日期加n天
			break;
		case 3:
			rightNow.add(Calendar.HOUR, dif);// 日期加n小时
			break;
		case DATE_ADD_MINUTE:
			rightNow.add(Calendar.MINUTE, dif);// 日期加n分钟
			break;
		case 5:
			rightNow.add(Calendar.SECOND, dif);// 日期加n秒
			break;
		default:
			break;
		}

		Date dt1 = rightNow.getTime();
		return dt1;
	}

	/**
	 * DES解密 所有解密的数据都先统一转换成大写再解密,和旧版后台一致
	 * 
	 * @author pengyi
	 * @date 20150828
	 * @param text
	 * @return
	 */
	public static String toDecrypt(String text) {
		try {
			if (StringUtils.isEmpty(text.toUpperCase()))
				return "";
			return DES.decrypt(text);
		} catch (Exception ex) {
			return text;
		}
	}

	/**
	 * DES加密 所有加密的数据都统一转换成大写,和旧版后台一致
	 * 
	 * @author pengyi
	 * @date 20150911
	 * @param text
	 * @return
	 */
	public static String encrypt(String text) {
		try {
			if (StringUtils.isEmpty(text))
				return "";
			return DES.encrypt(text).toUpperCase();
		} catch (Exception ex) {
			return text;
		}
	}

	/**
	 * 判断当月有几天
	 * 
	 * @author 茹化肖
	 * @date 20150828
	 * @param text
	 * @return
	 */
	public static Integer GetMixDay(String year, String month) {
		try {
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.YEAR, Integer.parseInt(year));
			cal.set(Calendar.MONTH, Integer.parseInt(month) - 1);// Java月份从0开始算
			int dateOfMonth = cal.getActualMaximum(Calendar.DATE);
			return dateOfMonth;

		} catch (Exception ex) {
			return 0;
		}

	}

	/**
	 * 获取时间中的月份
	 * 
	 * @author 茹化肖
	 * @param 1:年 2:月 3:日 4:时 :5:分 6:秒
	 * @return 返回对应类型数值
	 */
	public static Integer GetInDate(Date date, int type) {
		int ret = 0;
		try {
			Calendar c = Calendar.getInstance();// 可以对每个时间域单独修改
			int year = c.get(Calendar.YEAR);// 年
			int month = c.get(Calendar.MONTH) + 1;// 月
			int day = c.get(Calendar.DATE);// 日
			int hour = c.get(Calendar.HOUR_OF_DAY);// 时
			int minute = c.get(Calendar.MINUTE);// 分
			int second = c.get(Calendar.SECOND); // 秒
			switch (type) {
			case 1:
				ret = year;
				break;
			case 2:
				ret = month;
				break;
			case 3:
				ret = day;
				break;
			case 4:
				ret = hour;
				break;
			case 5:
				ret = minute;
				break;
			case 6:
				ret = second;
				break;
			}
			return ret;

		} catch (Exception ex) {
			return 0;
		}
	}

	public static Date strtoDate(String strDate) {
		Date date = null;
		try {
			if (null != strDate && !strDate.equals("")) {
				strDate = strDate.replace("T", " ");
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
				date = format.parse(strDate);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return date;
	}

	public static String nullToEmptyStr(String str) {
		if (null == str) {
			str = "";
		}
		return str;
	}

	public static float decimalToEmptyStr(BigDecimal obj) {
		float f = 0;
		if (null != obj) {
			f = obj.floatValue();
		}
		return f;
	}

	/**
	 * double相加 2016年7月27日 15:04:46 窦海超
	 * */
	public static double doubleSum(double num1, double num2) {
		BigDecimal b1 = BigDecimal.valueOf(num1);
		BigDecimal b2 = BigDecimal.valueOf(num2);
		return new Double(b1.add(b2).doubleValue());
	}

	/**
	 * double 四舍五入 2016年7月27日 15:20:47 窦海超
	 * */
	public static double doubleRound(double f) {
		BigDecimal b = BigDecimal.valueOf(f);
		return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	public static String strRound(BigDecimal b){
		return b.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
	}
	
	public static BigDecimal decimalRound(BigDecimal bd) {
		return bd.setScale(2, BigDecimal.ROUND_HALF_UP);
	}
	/**
	 * 格式话金额
	 * 
	 */
	public static String formatBanlance(BigDecimal i) {
		if (i==null) {
			return "0.00";
		}
		DecimalFormat myformat = new DecimalFormat();
		myformat.applyPattern("##.00");
		String res= myformat.format(i);
		if (res.indexOf(".")==0) {
			return "0"+res;
		}
		return res;
	}

	/**
	 * 将source中的Emoji字符(主要是手机端表情)替换为空串
	 * @param source 可能包含Emoji字符的字符串
	 * @author zhaohl
	 * @date 20170123
	 * @return 返回处理后的字符串
	 */
	public static String filterEmoji(String source) {  
       return filterEmoji(source,"");  
    }

	/**
	 * 将source中的Emoji字符(主要是手机端表情)替换为target
	 * @param source 可能包含Emoji字符的字符串
	 * @param target 将source中的Emoji字符替换为这个字符
	 * @author zhaohl
	 * @date 20170123
	 * @return 返回处理后的字符串
	 */
	public static String filterEmoji(String source,String target) {  
        if(source != null&&!source.isEmpty()){
        	if (target==null) {
        		target="";
			}
        	//过滤大于四个字节的utf8的字符串
        	//StringUtils.filterOffUtf8Mb4(source);
        	String tempString=source;
            Pattern emoji = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE ) ;
            Matcher emojiMatcher = emoji.matcher(tempString);
            if (emojiMatcher.find()){
            	tempString= emojiMatcher.replaceAll(target);
            }
            return tempString.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", target);  
       }
       return source;  
    }
	/**
	 * 判断给定的类型是否为基本类型（非用户自定义的class）
	 * @param type 要判断的类型
	 * @author zhaohl
	 * @date 20170124
	 * @return 返回boolean，true表示是基本类型，false表示非基本类型
	 */
	public static boolean isBaseObj(Class type){
		if (type==int.class||
				type==Integer.class||
				type==double.class||
				type==Double.class||
				type==float.class||
				type==Float.class||
				type==long.class||
				type==Long.class||
				type==short.class||
				type==Short.class||
				type==boolean.class||
				type==Boolean.class||
				type==byte.class||
				type==Byte.class||
				type==char.class||
				type==Character.class||
				type==String.class) {
			return true;
		}
		return false;
	}
	/**
	 * 通过反射将给定的对象字符串类型的属性值（只处理一级，不会递归处理）中的Emoji表情字符替换为空串
	 * @param bean 要处理的对象
	 * @param target 将bean中的Emoji字符替换为这个字符
	 * @author zhaohl
	 * @date 20170124
	 */
	public static void replaceEmoji(Object bean,String target) throws Exception{
		if (bean==null) {
			return;
		}
		if (isBaseObj(bean.getClass())) {
			return;
		}
		Object obj=null;
		String tempvalue="";
		String afterEmojiTempvalue="";
		long begin=System.currentTimeMillis();
		Field[] fields = bean.getClass().getDeclaredFields();
		for (Field field : fields) {
			if(field.getType()==String.class){
				field.setAccessible(true);
				obj=field.get(bean);
				if (obj!=null) {
					tempvalue=obj.toString();
					if (tempvalue!=null&&!tempvalue.trim().isEmpty()) {
						afterEmojiTempvalue=filterEmoji(tempvalue,target);
						if (!tempvalue.equals(afterEmojiTempvalue)) {
							field.set(bean,afterEmojiTempvalue) ;        //给属性设值  
						}
					} 
				}
			}
		}
		logger.debug("替换Emoji表情字符时耗时:"+(System.currentTimeMillis()-begin));
	}
	/**
	 * 将给定的对象数组中的实体的字符串类型的属性值中的Emoji表情字符替换为空串
	 * @param args 要处理的对象数组
	 * @param sql sql语句是update或insert时,
	 * 如果sql的参数(对象数组)的属性值中包含Emoji表情字符，
	 * 默认情况下mysql会报异常Incorrect string value: '\xF0\x9F\x94\xA8\xE5\xB9...' for column 'remark' at row 1
	 * @param target 将args中的Emoji字符替换为这个字符
	 * @author zhaohl
	 * @date 20170124
	 * @return 处理后的对象数组
	 */
	public static Object[] filterEmojiBySql(Object[] args,String sql,String target){
		if (args==null||args.length==0) {
			return args;
		}
		if (sql==null||sql.trim().isEmpty()) {
			return args;
		}

		try {
			String compareSql=sql.toLowerCase();
	        if (compareSql.indexOf("update")>=0||
	        		compareSql.indexOf("insert")>=0) {
	        	//如果最终的sql中没包含Emoji字符，则不用过滤入参实体中的Emoji字符了
	        	String afterEmojiSql=filterEmoji(compareSql,target);
				if (afterEmojiSql.equals(compareSql)) {
					return args;
				}
				
        		String tempvalue="";
        		String afterEmojiTempvalue="";
        		for (int i = 0; i < args.length; i++) {
        			if (args[i]==null) {
						continue;
					}
        			if (args[i] instanceof String) {
        				tempvalue=args[i].toString();
        				if (tempvalue!=null&&!tempvalue.trim().isEmpty()) {
							afterEmojiTempvalue=filterEmoji(tempvalue,target);
							if (!tempvalue.equals(afterEmojiTempvalue)) {
								args[i]=afterEmojiTempvalue;       
							}
						} 
					}else if (args[i] instanceof List&&((ArrayList)args[i]).size()>0) {
            			for (Object object : (ArrayList)args[i]) {
            				replaceEmoji(object,target);
						}
					}else {
						replaceEmoji(args[i],target);
					}
				}
			}
		} catch (Exception e) {
			logger.error("替换Emoji表情字符时异常:"+e.getMessage());
		}

    	return args;
	}


	/**
	 * @method：为空返回无
	 * @author：dongliyan
	 * @date：2017/11/7 13:38
	 * @description：为空返回无
	 */
	public static String nullToWUStr(String str) {
		if (StringUtils.isEmpty(str)) {
			str = "无";
		}
		return str;
	}
	public static String filterCauseBy(Exception ex){
		if (ex==null) {
			return "";
		}
		String stackTrace = StringUtils.getStackTrace(ex);
		return filterCauseBy(stackTrace);
	}
	public static String filterCauseBy(String stackTrace){
		if (stackTrace==null||stackTrace.trim().isEmpty()) {
			return "";
		}
		try {
			String b=stackTrace;
			int index=stackTrace.indexOf("Caused by:");
			if (index>0) {
				b=stackTrace.substring(index);
			}
			int end=b.indexOf("\r\n\tat ");
			if (end<0) {
				end=b.indexOf(" at ");
			}
			if (end<0) {
				end=b.indexOf("at ");
			}
			if (end>0) {
				return b.substring(0, end).trim().replace("\r\n", "");
			}
		} catch (Exception e) {
			//: handle exception
		}
		return stackTrace;
	}
	/**
	 * 对图片路径进行特殊处理（是否包含old）
	 * @param path
	 * @return
	 */
	public static String getImgUrl(String path){
		if (StringUtils.isEmpty(path)||path.trim().isEmpty()) {
			return "";
		}
		path=path.trim();
		if (path.contains("Old")&&!path.endsWith(".jpg")) {
			return path + ".jpg";
		}
		return path;
	}
	/**
	 * 拼接图片域名和图片路径
	 * 对图片路径进行特殊处理（是否包含old）
	 * @param imgUrl
	 * @param path
	 * @return
	 */
	public static String getDomainImgUrl(String imgUrl,String path){
		if (StringUtils.isEmpty(path)||path.trim().isEmpty()) {
			return "";
		}
		path=path.trim();
		if (path.startsWith("http://")||path.startsWith("https://")) {
			return path;
		}
		
		if (StringUtils.isEmpty(imgUrl)||imgUrl.trim().isEmpty()) {
			return path;
		}
		imgUrl=imgUrl.trim();
		if (!imgUrl.startsWith("http://")&&!imgUrl.startsWith("https://")) {
			return path;
		}
		String tempImgUrl=imgUrl;
		String tempPath=path;
		if (tempImgUrl.endsWith("/")) {
			tempImgUrl=tempImgUrl.substring(0, tempImgUrl.lastIndexOf("/"));
		}
		if (tempPath.startsWith("/")) {
			tempPath=tempPath.substring(1);
		}
		return tempImgUrl+"/"+getImgUrl(tempPath);
	}

	/**
	 * 通过给定的分隔符分隔参数字符串
	 * @param param userId=270022;token=6E7AF739079CEC23C68A4E9711655FFD55D9ABD395FD7509;
	 *             或userId=270022&token=6E7AF739079CEC23C68A4E9711655FFD55D9ABD395FD7509
	 * @param split
	 * @return
	 */
	public static Map<String,String> splitParamStr(String param,String split){
		Map<String,String> resultMap=new HashMap<>();
		if(StringUtils.isEmpty(param)||StringUtils.isEmpty(split)){
			return resultMap;
		}
		String [] datas=param.split(split);
		for (String pa : datas) {
			String[] kv=pa.split("=");
			if(kv.length==2&&!kv[0].trim().isEmpty()){
				resultMap.put(kv[0].trim(),kv[1].trim());
			}
		}
		return resultMap;
	}
}
